package cn.mabach.oauth2.project.controller;


import cn.mabach.exception.RRException;
import cn.mabach.oauth2.project.entity.QQUserInfo;
import cn.mabach.oauth2.project.entity.SocialUser;
import cn.mabach.oauth2.project.feign.MemberServiceFeign;
import cn.mabach.member.entity.MemberEntity;
import cn.mabach.oauth2.properties.SecurityProperties;
import cn.mabach.result.RS;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;


import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

@Controller
@Slf4j
public class LoginController {



    private String APLY_TOKEN_URL="https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&state=ok";
    private String QQ_LOGINBACK_URL="https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s";
    private String QQ_OPENID_URL="https://graph.qq.com/oauth2.0/me?access_token=%s";
    private String QQINFO="https://graph.qq.com/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s";
    private static final String ERROR_WEB_500="500";
    private static final String QQ_SOCIAL_USER_KEY="qq_social_user_key";
    private static final String INDEX_URL="http://www.mabach.cn/api-portal/portal/info";
    private static final String QQ_LOGIN="http://www.mabach.cn/api-oauth/login/qq?qq=";
    private static final String PRE_QQ_LOGIN="http://www.mabach.cn/api-oauth/preqq?openId=";
    private static final String RELATE_QQ="http://www.mabach.cn/api-oauth/relateQQ?openId=";

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private SecurityProperties securityProperties;

    @Autowired
    private MemberServiceFeign memberServiceFeign;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;




    @GetMapping("/toLogin")
    public String toLogin(@RequestParam(value = "from",required = false,defaultValue = "") String from,Model model ){


        log.info("from:---------{}",from);

        if (StringUtils.isEmpty(from)){
            model.addAttribute("from",INDEX_URL);
        }else {
            model.addAttribute("from",from);
        }




        return "login";
    }





//    引导用户点击授权连接获取授权码
    @GetMapping("/toQQLogin")
    public String toQQLogin(){
        String url = String.format(APLY_TOKEN_URL, securityProperties.getSocial().getQq().getAppId(),
                securityProperties.getSocial().getQq().getLoginBackUrl());

        return "redirect:"+url;
    }

//    根据回调地址获取qq号
    @RequestMapping("/qqloginback")
    public String qqLoginBack(String code,HttpServletRequest request){
//        获取token
        String url = String.format(QQ_LOGINBACK_URL, securityProperties.getSocial().getQq().getAppId(),
                securityProperties.getSocial().getQq().getAppKey(), code, securityProperties.getSocial().getQq().getLoginBackUrl());
        String rerult = restTemplate.getForObject(url, String.class);
        if (StringUtils.isEmpty(rerult)){
            return ERROR_WEB_500;
        }
        String token = StringUtils.substringBetween(rerult, "token=", "&");

//获取openId
        String openIdUrl = String.format(QQ_OPENID_URL, token);
        String callback = restTemplate.getForObject(openIdUrl, String.class);
        if (StringUtils.isEmpty(callback)){
            return ERROR_WEB_500;
        }
        String  openId= StringUtils.substringBetween(callback, "\"openid\":", "}").replace("\"","");
//获取qqUserInfo
        String infoUrl = String.format(QQINFO, token, securityProperties.getSocial().getQq().getAppId(), openId);
        String info = restTemplate.getForObject(infoUrl, String.class);

        QQUserInfo qqUserInfo = JSON.parseObject(info, QQUserInfo.class);

        SocialUser socialUser = new SocialUser();
        socialUser.setHeadImg(qqUserInfo.getFigureurl_qq_1());
        socialUser.setNickNake(qqUserInfo.getNickname());
        socialUser.setOpenId(openId);
        socialUser.setProvider("qq");
//查询是否绑定过
        MemberEntity memberEntity = memberServiceFeign.getByIByqqOpenId(openId).getData();
        if (memberEntity==null){

            redisTemplate.boundHashOps(QQ_SOCIAL_USER_KEY).put(openId,socialUser);
            redisTemplate.expire(openId,60*10,TimeUnit.SECONDS);

//没有绑定过则跳转到绑定页面
            return "redirect:"+RELATE_QQ+openId;
        }

//







        return "redirect:"+PRE_QQ_LOGIN+openId;


    }
//qq登录页面
    @RequestMapping("/preqq")
    public String preqq(@RequestParam(value = "openId") String openId, Model model, HttpServletRequest request) {

        if (StringUtils.isEmpty(openId)){
            throw new RRException("preqq(),openId为空");
        }

        model.addAttribute("openId",openId);
        setFrom(model,request);

        return "preqq";

    }

//    关联QQ
    @GetMapping("/relateQQ")
    public String relateQQ(@RequestParam("openId") String openId,Model model,HttpServletRequest request){

        if (StringUtils.isEmpty(openId)){
            return ERROR_WEB_500;
        }
        SocialUser socialUser = (SocialUser) redisTemplate.boundHashOps(QQ_SOCIAL_USER_KEY).get(openId);


        model.addAttribute("socialUser",socialUser);
        redisTemplate.boundHashOps(QQ_SOCIAL_USER_KEY).delete(openId);

//        根据ip传递登陆前的地址给前端
        setFrom(model, request);


        return "relate";
    }




    //关联QQ与账号注册
    @RequestMapping("/register/qq")
    @ResponseBody
    public RS registerQQ(String username,String password,String openId) {

        if(StringUtils.isEmpty(username)){
            return RS.error("账号不能为空");
        }
        if(StringUtils.isEmpty(password)){
            return RS.error("密码不能为空");
        }
        if(StringUtils.isEmpty(openId)){
            return RS.error("openId不能为空");
        }

//根据openId从redis中取出用户信息，然后注册
        RS rs = memberServiceFeign.saveByOpenId(username, password, openId);
        if (!rs.isFlag()){
            return RS.error("服务器出错，请联系管理员");
        }



        return RS.ok("关联成功");



    }

    @RequestMapping("/toLogin/mobile")
    public String loginMobile(@RequestParam(value = "from",required = false) String from,Model model) {

        if (StringUtils.isEmpty(from)){
            model.addAttribute("from",INDEX_URL);
        }else {
            model.addAttribute("from",from);
        }


        return "login-mobile";

    }

    //    传递登录前的跳转地址给前端
    private void setFrom(Model model, HttpServletRequest request) {
        String remoteAddr = request.getRemoteAddr();
        String fromUrl = stringRedisTemplate.boundValueOps(remoteAddr).get();
        if (StringUtils.isEmpty(fromUrl)){

            model.addAttribute("from",INDEX_URL);
        }else {
            model.addAttribute("from",fromUrl);
        }
    }



}
